/*
 * GlobalServer.cpp
 *
 *  Created on: 2009-04-17
 *      Author: Jacek Suchowski
 *
 * Implementacja głównej klasy odpowieadającej za nasłuchiwanie na nadchodzące połączenia
 * i tworzenie nowych wątków dla każdego połączonego klienta
 */

#include "GlobalServer.h"
#include "ConfigChanger.h"
#include "ClientController.h"
#include "MacCollector.h"
#include "structures.h"
#include "Log.h"
#include <cstdlib>
#include <iostream>
using namespace std;

namespace tftp_server
    {

    void GlobalServer::init()
	{
	if (isMacCollector)
	    macCollector = new MacCollector(true);
	else
	    macCollector = new MacCollector();
	if (isConfigChanger)
	    ConfigChanger configChanger(true, configPort,
		    configPassword.c_str());
	}

    void GlobalServer::listen()
	{
	struct sockaddr_in clientName;
	struct sockaddr_in serverName;
	struct sockaddr_in newClientName;
	socklen_t newClientNameLength = sizeof(newClientName);
	char buffer[1024];

	init();

	sock = socket(AF_INET, SOCK_DGRAM, 0);

	if (sock == -1)
	    {
	    Loger::getInstance().send(Log(
		    "GlobalServer: Fail to open listening socket!", 1));
	    exit(1);
	    }

	clientName.sin_family = AF_INET;
	clientName.sin_addr.s_addr = htonl(INADDR_ANY);
	clientName.sin_port = htons(port);

	if (bind(sock, (struct sockaddr *) &clientName, sizeof clientName)
		== -1)
	    {
	    Loger::getInstance().send(Log(
		    "GlobalServer: Fail to bind listening socket !", 2));
	    exit(1);
	    }

	while (1)
	    {
	    if (recvfrom(sock, buffer, 1024, 0,
		    (struct sockaddr *) &newClientName, &newClientNameLength)
		    == -1)
		{
		Loger::getInstance().send(Log(
			"GlobalServer: Fail to read package from client !", 2));
		}
	    else
		{
		tempSock = socket(AF_INET, SOCK_DGRAM, 0);
		if (tempSock == -1)
		    {
		    Loger::getInstance().send(Log(
			    "GlobalServer: Fail to open client socket !", 2));
		    }

		serverName.sin_family = AF_INET;
		serverName.sin_addr.s_addr = htonl(INADDR_ANY);
		serverName.sin_port = htons(0);

		if (bind(tempSock, (struct sockaddr *) &serverName,
			sizeof serverName) == -1)
		    {
		    Loger::getInstance().send(Log(
			    "GlobalServer: Fail to bind client socket !", 2));
		    }
		Package package(buffer);
		ClientController temp = ClientController(true, tempSock,
			newClientName, package, macCollector);
		}
	    }

	close(sock);

	}

    GlobalServer::~GlobalServer()
	{
	delete macCollector;
	close(sock);
	close(tempSock);
	}

    }
